package edu.hawaii.ics414.blackjack.player;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import edu.hawaii.ics414.blackjack.card.Card;
import edu.hawaii.ics414.blackjack.card.GameDeck;
import edu.hawaii.ics414.blackjack.card.Rank;
import edu.hawaii.ics414.blackjack.card.Suit;

/**
 * Tests the ExperiencedPlayer class.
 * 
 * @author Branden Ogata
 *
 */

public class TestExperiencedPlayer
{
  /**
   * Tests the methods of the ExperiencedPlayer class.
   * Since TestPlayer tests all of the methods of the Seat interface,
   * these tests will only involve the methods specifically in the ExperiencedPlayer class.
   * 
   */
  
  @Test
  public void test()
  {
    AIPlayer experienced = new ExperiencedPlayer(100);
    GameDeck deck = new GameDeck(6);
    
    // Test getCards for the NovicePlayer class
    experienced.startHand(deck);
    String cards = experienced.getCards();
    
    for (Card c : experienced.hands[0])
    {
      if (c != null)
      {
        assertTrue("Card should be included", cards.contains(c.toString()));
        cards = cards.substring(3);
      }
    }    
    
    // Hands to stay on    
    // Hard >=17 vs. Dealer >=7
    TestPlayer.makeHardHand(experienced, deck, 17);
    assertEquals("Hard >=17 " + experienced.getCards() + " vs. Dealer >=7: STAND", 
                 Action.STAND, 
                 experienced.getMove(deck, 0, new Card(Suit.CLUBS, Rank.SEVEN)));
    // Hard >=12 vs. Dealer 4-6
    TestPlayer.makeHardHand(experienced, deck, 12);
    assertEquals("Hard >=12 " + experienced.getCards() + " vs. Dealer 4-6: STAND", 
                 Action.STAND, 
                 experienced.getMove(deck, 0, new Card(Suit.DIAMONDS, Rank.FIVE)));
    // Hard >=13 vs. Dealer 2-3
    TestPlayer.makeHardHand(experienced, deck, 13);
    assertEquals("Hard >=13 " + experienced.getCards() + " vs. Dealer 2-3: STAND", 
                 Action.STAND, 
                 experienced.getMove(deck, 0, new Card(Suit.HEARTS, Rank.THREE)));
    // Soft >=19 vs. Dealer Any
    TestPlayer.makeSoftHand(experienced, deck, 19);
    assertEquals("Soft >=19 " + experienced.getCards() + " vs. Dealer Any: STAND", 
                 Action.STAND, 
                 experienced.getMove(deck, 0, new Card(Suit.SPADES, Rank.EIGHT)));
    // Soft >=18 vs. Dealer 2-8
    TestPlayer.makeSoftHand(experienced, deck, 18);
    assertEquals("Soft >=18 " + experienced.getCards() + " vs. Dealer 2-8: STAND", 
                 Action.STAND, 
                 experienced.getMove(deck, 0, new Card(Suit.CLUBS, Rank.TWO)));

    // Hands to hit on
    // Hard <=16 vs. Dealer >=7
    TestPlayer.makeHardHand(experienced, deck, 16);
    assertEquals("Hard <=16 " + experienced.getCards() + " vs. Dealer >=7: HIT", 
                 Action.HIT, 
                 experienced.getMove(deck, 0, new Card(Suit.DIAMONDS, Rank.SEVEN)));
    // Hard <=12 vs. Dealer 2-3
    TestPlayer.makeHardHand(experienced, deck, 12);
    assertEquals("Hard <=12 " + experienced.getCards() + " vs. Dealer 2-3: HIT", 
                 Action.HIT, 
                 experienced.getMove(deck, 0, new Card(Suit.HEARTS, Rank.TWO)));
    // Hard <=8 vs. Dealer 4-6
    TestPlayer.makeHardHand(experienced, deck, 8);
    assertEquals("Hard <=8 " + experienced.getCards() + " vs. Dealer 4-6: HIT", 
                 Action.HIT, 
                 experienced.getMove(deck, 0, new Card(Suit.SPADES, Rank.FIVE)));
    // Soft <=18 vs. Dealer >=9
    TestPlayer.makeSoftHand(experienced, deck, 18);
    assertEquals("Soft <=18 " + experienced.getCards() + " vs. Dealer >=9: HIT", 
                 Action.HIT, 
                 experienced.getMove(deck, 0, new Card(Suit.CLUBS, Rank.TEN)));
    // Soft <=17 vs. Dealer Any
    TestPlayer.makeSoftHand(experienced, deck, 17);
    assertEquals("Soft <=17 " + experienced.getCards() + " vs. Dealer Any: HIT", 
                 Action.HIT, 
                 experienced.getMove(deck, 0, new Card(Suit.HEARTS, Rank.SEVEN)));
    
    // Hands to double down on
    // Hard 11 vs. Dealer <=10
    TestPlayer.makeHardHand(experienced, deck, 11);
    assertEquals("Hard 11 " + experienced.getCards() + " vs. Dealer <= 10", 
                 Action.DOUBLE_DOWN, 
                 experienced.getMove(deck, 0,  new Card(Suit.DIAMONDS, Rank.JACK)));
    // Hard 10 vs. Dealer <=9
    TestPlayer.makeHardHand(experienced, deck, 10);
    assertEquals("Hard 10 " + experienced.getCards() + " vs. Dealer <= 9", 
                 Action.DOUBLE_DOWN, 
                 experienced.getMove(deck, 0,  new Card(Suit.HEARTS, Rank.NINE)));
    // Hard 9 vs. Dealer 3-6
    TestPlayer.makeHardHand(experienced, deck, 9);
    assertEquals("Hard 9 " + experienced.getCards() + " vs. Dealer 3-6", 
                 Action.DOUBLE_DOWN, 
                 experienced.getMove(deck, 0,  new Card(Suit.SPADES, Rank.SIX)));
    // Soft 13-18 vs. Dealer 5-6
    TestPlayer.makeSoftHand(experienced, deck, 18);
    assertEquals("Soft 13-18 " + experienced.getCards() + " vs. Dealer 5-6", 
                 Action.DOUBLE_DOWN, 
                 experienced.getMove(deck, 0,  new Card(Suit.CLUBS, Rank.FIVE)));
    // Soft 15-18 vs. Dealer 4
    TestPlayer.makeSoftHand(experienced, deck, 15);
    assertEquals("Soft 15-18 " + experienced.getCards() + " vs. Dealer 4", 
                 Action.DOUBLE_DOWN, 
                 experienced.getMove(deck, 0,  new Card(Suit.DIAMONDS, Rank.FOUR)));
    // Soft 17-18 vs. Dealer 3
    TestPlayer.makeSoftHand(experienced, deck, 17);
    assertEquals("Soft 17-18 " + experienced.getCards() + " vs. Dealer 3", 
                 Action.DOUBLE_DOWN, 
                 experienced.getMove(deck, 0,  new Card(Suit.HEARTS, Rank.THREE)));
    
    // Hands to split on
    // Ace Pair vs. Dealer Any 
    TestPlayer.makeSplittableHand(experienced, deck, Rank.ACE);
    assertEquals("Ace Pair " + experienced.getCards() + " vs. Dealer Any", Action.SPLIT, 
                                            experienced.getMove(deck, 0, deck.draw())); 
    
    // 8 Pair vs. Dealer Any 
    TestPlayer.makeSplittableHand(experienced, deck, Rank.EIGHT);
    assertEquals("Eight Pair " + experienced.getCards() + " vs. Dealer Any", Action.SPLIT, 
                                              experienced.getMove(deck, 0, deck.draw())); 
    
    // 9 Pair vs. Dealer 9, 8, 6, 5, 4, 3, 2
    TestPlayer.makeSplittableHand(experienced, deck, Rank.NINE);
    assertEquals("Nine Pair " + experienced.getCards() + " vs. Dealer 9", Action.SPLIT, 
                                           experienced.getMove(deck, 0, 
                                                               new Card(Suit.CLUBS, Rank.NINE))); 
    
    // 7 Pair vs. Dealer <7
    TestPlayer.makeSplittableHand(experienced, deck, Rank.SEVEN);
    assertEquals("Seven Pair " + experienced.getCards() + " vs. Dealer < 7", Action.SPLIT, 
                                              experienced.getMove(deck, 0, 
                                                                  new Card(Suit.SPADES, Rank.SIX))); 
    
    // 6 Pair vs. Dealer 3-6
    TestPlayer.makeSplittableHand(experienced, deck, Rank.ACE);
    assertEquals("Six Pair " + experienced.getCards() + " vs. Dealer 3-6", Action.SPLIT, 
                                            experienced.getMove(deck, 0, 
                                                                new Card(Suit.DIAMONDS, 
                                                                         Rank.FIVE))); 
    
    // 2 Pair, 3 Pair vs. Dealer 4-7
    TestPlayer.makeSplittableHand(experienced, deck, Rank.TWO);
    assertEquals("Two Pair " + experienced.getCards() + " vs. Dealer 4-7", Action.SPLIT, 
                                            experienced.getMove(deck, 0, 
                                                                new Card(Suit.HEARTS, Rank.SEVEN))); 
    TestPlayer.makeSplittableHand(experienced, deck, Rank.THREE);
    assertEquals("Three Pair " + experienced.getCards() + " vs. Dealer 4-7", Action.SPLIT, 
                                              experienced.getMove(deck, 0,
                                                                  new Card(Suit.CLUBS, Rank.FOUR))); 
  }
}
